import orgCtrl from '@/ts/controller';
import { kernel, schema } from '@/ts/base';
import { IWorkTask } from '@/ts/core';
import { XWorkTask } from '@/ts/base/schema';

export const formatNumber = (num: number) => {
  return Number(Number(num).toFixed(2));
};
const dynamicPrecisionAdd = (a: any, b: any) => {
  const numbers = [a, b];
  let maxPrecision = 0;
  numbers.forEach((num) => {
    const numStr = num.toString();
    const decimalIndex = numStr.indexOf('.');
    const precision = decimalIndex === -1 ? 0 : numStr.length - decimalIndex - 1;
    maxPrecision = Math.max(maxPrecision, precision);
  });

  const multiplier = Math.pow(10, maxPrecision);
  let sum = 0;
  numbers.forEach((num) => {
    sum += num * multiplier;
  });

  return sum / multiplier;
};
export const mergeData = (data: any[][]): any[] => {
  const mergedData = data.reduce((acc: any, item: any) => {
    const id = item[0].mainKey.id;
    if (!acc[id]) {
      acc[id] = {
        ...item[0], // mainKey 对象
        values: {},
      };
    }

    for (let i = 1; i < item.length; i++) {
      const key = Object.keys(item[i])[0];
      if (!acc[id].values[key]) {
        acc[id].values[key] = 0;
      }
      acc[id].values[key] = dynamicPrecisionAdd(
        item[i][key] === undefined ? 0 : Number.isNaN(item[i][key]) ? 0 : item[i][key],
        acc[id].values[key],
      );
    }

    return acc;
  }, {});
  return Object.values(mergedData).map((item: any) => {
    const { values, ...rest } = item;
    return {
      ...rest,
      ...values,
    };
  });
};

export const buildTree = (items: any[], parentId: any, level: number): any[] => {
  const tree: any[] = [];
  items.forEach((item) => {
    if (item.parentId === parentId) {
      const children = buildTree(items, item.id, level + 1);
      const node = { ...item, level, children };
      tree.push(node);
    }
  });
  return tree;
};
const treeFind = (tree: { children: any }, targetId: any, result = null) => {
  if (!tree.children) return result;
  for (const child of tree.children) {
    if (child.value === targetId) {
      return child;
    } else {
      result = treeFind(child, targetId, result);
    }
  }
  return result;
};

export const findParentNodeByIdAndLevel = (
  tree: any[],
  selectedId: any,
  targetLevel: number,
  currentLevel = 1,
) => {
  for (let node of tree) {
    if (node.value == selectedId) {
      return node;
    } else {
      if (currentLevel === targetLevel && node.children && treeFind(node, selectedId)) {
        return node;
      }
      if (node.children.length > 0) {
        const parentNode: any = findParentNodeByIdAndLevel(
          node.children,
          selectedId,
          targetLevel,
          currentLevel + 1,
        );
        if (parentNode) {
          return parentNode;
        }
      }
    }
  }
  return null;
};
export const getUserDetail = async (
  value: string,
  setUserDetail: (detail: { [key: string]: string }) => void,
) => {
  const res = await orgCtrl.user.findMetadata<schema.XEntity>(value);
  setUserDetail({ ...{}, [value]: res?.name });
};

/**
 * 根据设计流程获取审批节点
 * @param resource
 * @returns
 */
export async function getWorkNodes(resource: any): Promise<any[]> {
  const workNode: any[] = [];

  try {
    const fetchOtherNodes = async (destShareId: string, destWorkId: string) => {
      const result = await kernel.queryWorkNodes({
        id: destWorkId,
        shareId: destShareId,
      });
      return result.success ? result.data : [];
    };
    const addWorkNode = (data: any) => {
      workNode.push({
        nodeId: data.id,
        id: data?.primaryId,
        name: data.name,
        type: data.type,
        destId: data?.destId,
        destType: data?.destType,
        destName: data?.destName,
        roleDestId: data?.roleDestId,
        extra: data?.extra,
      });
    };
    const convertProcessNode = async (data: any) => {
      if (data.id && data.destType === '身份' && data.type === '审批') {
        addWorkNode(data);
      }
      if (data.id && data.destType === '身份' && data.type === '自由节点') {
        const target = orgCtrl.targets.find((item) => item.id === data.destId);
        if (target) {
          const defaultRoleIds =
            data.defaultRoleIds ?? JSON.parse(data.resource).defaultRoleIds;
          if (defaultRoleIds) {
            await Promise.all(
              defaultRoleIds.map((roleId: string) => {
                const role = target.identitys.find((item) => {
                  return item.id == roleId;
                });
                if (role) {
                  addWorkNode({
                    ...data,
                    roleDestId: role.id,
                    destName: `[${data.destName}]-${role.name}`,
                    extra: role.metadata,
                  });
                }
              }),
            );
          }
        }
      }
      if (data.id && data.type === '条件' && data.branches.length > 0) {
        await Promise.all(
          data.branches.map(async (item: any) => {
            if (item.children) {
              await convertProcessNode(item.children);
            }
          }),
        );
      }
      if (data.destType === '其他办事') {
        const resourceData = data.resource ? JSON.parse(data.resource) : {};
        const defineId = data.destWorkId ?? resourceData.destWorkId;
        const otherBusinessNodes = await fetchOtherNodes(data.destShareId, defineId);
        await convertProcessNode(otherBusinessNodes);
      }
      if (data.children) {
        await convertProcessNode(data.children);
      }
    };
    await convertProcessNode(resource);
  } catch (error) {
    console.log('error', error);
  }
  return workNode;
}

const extractTasks = (data: any[], taskKey = 'tasks', recordKey = 'records'): any[] => {
  const result: any[] = [];
  const traverse = (items: any[]) => {
    items.forEach((item) => {
      if (item[taskKey] && Array.isArray(item[taskKey])) {
        traverse(item[taskKey]);
      }
      if (item[recordKey] && item[recordKey].length > 0) {
        result.push({
          ...item,
          [taskKey]: undefined,
          instance: undefined,
        });
      }
    });
  };
  traverse(data);
  return result;
};

/**
 * 获取办事任务
 * @param work
 * @returns
 */
export async function fetchTasks(work: IWorkTask): Promise<XWorkTask[]> {
  try {
    const result = await work.loadTasksData();
    return extractTasks(result);
  } catch (error) {
    const instanceTasks = work.instance?.tasks ?? [];
    return extractTasks(instanceTasks);
  }
}
